package javaz.zxing.qrcode;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;

/**
 * Quick Response Code handler
 * 
 * @author SUCCESS\tungo
 * @date 2013-11-21
 */
public class QRCodeUtil {

	/**
	 * Create QRCode with result is byte[] data type
	 * 
	 * @param data
	 *            String
	 * @return byte[] data of PNG image
	 */
	public static byte[] create(String data) {
		ByteArrayOutputStream out = QRCode.from(data).to(ImageType.PNG)
				.stream();
		return out.toByteArray();
	}

	/**
	 * Create QRCode with result is byte[] data type
	 * 
	 * @param data
	 *            String
	 * @param size
	 *            Integer
	 * @return byte[] data of PNG image
	 */
	public static byte[] create(String data, Integer size) {
		ByteArrayOutputStream out = QRCode.from(data).to(ImageType.PNG)
				.withSize(size, size).stream();
		return out.toByteArray();
	}

	/**
	 * Create QRCode image with type PNG
	 * 
	 * @param data
	 *            String
	 * @param imgUrl
	 *            String
	 * @return Boolean
	 */
	public static Boolean create(String data, String imgUrl) {
		try {
			FileOutputStream fout = new FileOutputStream(new File(imgUrl));
			fout.write(create(data));
			fout.flush();
			fout.close();
			return Boolean.TRUE;
		} catch (IOException e) {
			return Boolean.FALSE;
		}
	}

	/**
	 * Create QRCode image with type PNG
	 * 
	 * @param data
	 *            String
	 * @param imgUrl
	 *            String
	 * @param size
	 *            Integer
	 * @return Boolean
	 */
	public static Boolean create(String data, String imgUrl, Integer size) {
		try {
			FileOutputStream fout = new FileOutputStream(new File(imgUrl));
			fout.write(create(data, size));
			fout.flush();
			fout.close();
			return Boolean.TRUE;
		} catch (IOException e) {
			return Boolean.FALSE;
		}
	}

	/**
	 * Read QRCode from an image
	 * 
	 * @param imgUrl
	 *            String
	 * @return String
	 */
	public static String read(String imgUrl) {
		try {
			FileInputStream input = new FileInputStream(imgUrl);
			BufferedImage bufferedImg = ImageIO.read(input);
			BufferedImageLuminanceSource buffer = new BufferedImageLuminanceSource(
					bufferedImg);
			HybridBinarizer binaries = new HybridBinarizer(buffer);
			BinaryBitmap binaryBitmap = new BinaryBitmap(binaries);
			Result result = new MultiFormatReader().decode(binaryBitmap);
			return result.getText();
		} catch (NotFoundException | IOException e) {
			return null;
		}
	}

}